package com.blog.admin.service;


import com.blog.admin.mapper.SysPermissionsMapper;
import com.blog.admin.vo.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
@Transactional
public class SysPermissionsService {
    @Autowired
    SysPermissionsMapper sysPermissionsMapper;
    @Autowired
    HttpServletRequest request;

    /**
     * 根据id获取角色
     *
     * @param id
     * @return
     */
    public SysRoleVO getRoleById(String id) {
        SysRoleVO sysRoleVO = sysPermissionsMapper.getRoleById(id);
        request.getSession().setAttribute("sysRoleVO", sysRoleVO);
        return sysRoleVO;
    }

    /**
     * 根据id获取菜单和角色
     *
     * @param id
     * @return
     */
    public SysRoleVO getMenuById(String id) {
        return sysPermissionsMapper.getMenuById(id);
    }

    /**
     * 修改用户权限
     *
     * @param jsonArray
     * @return
     */
    public boolean updatePermissions(JSONArray jsonArray) {
        //全部初始化
        for (Object obj : jsonArray) {
             SysMenuVO  sysMenuVO = new SysMenuVO();
             Map<String,Object> map = (Map<String, Object>) obj;
            sysMenuVO.setMenuRoleId((String) map.get("pk_role_menu"));
            sysMenuVO.setCheckStatus((Integer) map.get("checked"));
            sysPermissionsMapper.updatePermissions(sysMenuVO);
        }
        return true;
    }

    /**
     * 修改用户权限
     *
     * @param jsonArray
     * @return
     */
    public boolean updatePermissions(JSONArray jsonArray, String roleId) {
        SysRoleVO sysRoleVO = new SysRoleVO();
        sysRoleVO.setId(roleId);
        SysRoleVO menu = getMenuById(sysRoleVO.getId());
        //全部初始化
        for (SysMenuVO sysMenuVO : menu.getMenuList()) {
            sysMenuVO.setCheckStatus(0);
            sysPermissionsMapper.updatePermissions(sysMenuVO);
        }
        //将选中的修改
        hasChildren(jsonArray, roleId);
        return true;
    }

    public boolean hasChildren(JSONArray jsonArray, String roleId) {
        //将选中的修改
        for (Object object : jsonArray) {
            JSONObject jsonObject = JSONObject.fromObject(object);
            if (jsonObject.has("children")) {
                if (JSONArray.fromObject(jsonObject.get("children")).size() > 0) {
                    hasChildren(JSONArray.fromObject(jsonObject.get("children")), roleId);
                }
            }
            SysMenuRoleVO sysMenuRoleVO = new SysMenuRoleVO();
            sysMenuRoleVO.setPkMenu(jsonObject.getString("id"));
            sysMenuRoleVO.setPkRole(roleId);
            sysMenuRoleVO.setCheckStatus(1);
            sysPermissionsMapper.updatePermissionsByRoleAndMenu(sysMenuRoleVO);
        }
        return true;
    }

    /**
     * 获取所有菜单
     *
     * @return
     */
    public List<Map<String, Object>> getAllMeu() {
        return sysPermissionsMapper.getAllMenu();
    }


    /**
     * 初始化权限
     */
    public boolean initPermission(SysRoleVO sysRoleVO) {
        List<SysMenuRoleVO> sysMenuRoleVOList = new ArrayList<>();
        for (Map<String, Object> mapAll : getAllMeu()) {
            int i = 0;
            //所有菜单和当前用户菜单做比较
            for (SysMenuVO sysMenuVO : getMenuById(sysRoleVO.getId()).getMenuList()) {
                if (mapAll.get("authorityId").equals(sysMenuVO.getId())) {
                    i++;
                    break;
                }
            }
            if (i < 1) {
                SysMenuRoleVO sysMenuRoleVO = new SysMenuRoleVO();
                sysMenuRoleVO.setPkRole(sysRoleVO.getId());
                sysMenuRoleVO.setPkMenu(mapAll.get("authorityId").toString());
                sysMenuRoleVO.setCheckStatus(0);
                sysMenuRoleVOList.add(sysMenuRoleVO);
            }
        }
        if (sysMenuRoleVOList.size() > 0) {
            insertMenuRole(sysMenuRoleVOList);
        }
        return true;
    }


    /**
     * 获取当前角色的菜单
     */
    public List<Map<String, Object>> getThisRoleMenu(SysRoleVO sysRoleVO) {
        SysRoleVO menuRole = getMenuById(sysRoleVO.getId());
        List<Map<String, Object>> tree = getTree(menuRole.getMenuList());
        return tree;
    }


    /**
     * 获取菜单树
     *
     * @param menuList
     * @return
     */
    public List<Map<String, Object>> getTree(List<SysMenuVO> menuList) {
        List<Map<String, Object>> resultData = new ArrayList<>();
        Map<String, Object> parentData = new HashMap<>();
        for (SysMenuVO sysMenuVO : menuList) {
            if (StringUtils.isEmpty(sysMenuVO.parentId) || "-1".equals(sysMenuVO.parentId)) {
                parentData.put("id", sysMenuVO.getId());
                parentData.put("parentId", sysMenuVO.getParentId());
                parentData.put("title", sysMenuVO.getMenuName());
                parentData.put("href", sysMenuVO.getMenuUrl());
                parentData.put("menuRoleId", sysMenuVO.getMenuRoleId());
                parentData.put("checked", sysMenuVO.getCheckStatus()==1?true:false);
                List<Map<String, Object>> children =  findTree(menuList, sysMenuVO.getId());
                if (children.size()>0){
                    parentData.put("children", findTree(menuList, sysMenuVO.getId()));
                }
                resultData.add(parentData);
                parentData = new HashMap<>();
            }
        }
        return resultData;
    }

    /**
     * 遍历二叉树一条节点
     *
     * @param menuList
     * @param parentId
     * @return
     */
    public List<Map<String, Object>> findTree(List<SysMenuVO> menuList, String parentId) {
        List<Map<String, Object>> result = new ArrayList<>();
        Map<String, Object> child = new HashMap<>();
        for (SysMenuVO sysMenuVO : menuList) {
            if (sysMenuVO.getParentId().equals(parentId)) {
                child.put("id", sysMenuVO.getId());
                child.put("parentId", sysMenuVO.getParentId());
                child.put("title", sysMenuVO.getMenuName());
                child.put("menuRoleId", sysMenuVO.getMenuRoleId());
                child.put("checked", sysMenuVO.getCheckStatus() == 1 ? true : false);
                child.put("href", sysMenuVO.getMenuUrl());
                List<Map<String, Object>> children =  findTree(menuList, sysMenuVO.getId());
                if (children.size()>0){
                    child.put("children",children);
                }
            }
            if (!child.isEmpty()) {
                result.add(child);
            }

            child = new HashMap<>();
        }
        return result;
    }


    /**
     * 角色插入
     *
     * @param sysRoleVO
     * @return
     */
    public boolean insertRole(SysRoleVO sysRoleVO) {
        sysRoleVO.setCreateTime(new Date());
        return sysPermissionsMapper.insertRole(sysRoleVO) > 0 ? true : false;
    }

    /**
     * 修改角色
     *
     * @param sysRoleVO
     * @return
     */
    public boolean updateRole(SysRoleVO sysRoleVO) {
        sysRoleVO.setUpdateTime(new Date());
        return sysPermissionsMapper.updateRole(sysRoleVO) > 0 ? true : false;
    }

    /**
     * 角色删除
     *
     * @param sysRoleVO
     * @return
     */
    public boolean deleteRole(SysRoleVO sysRoleVO) {
        SysMenuRoleVO sysMenuRoleVO = new SysMenuRoleVO();
        sysMenuRoleVO.setPkRole(sysRoleVO.getId());
        SysUserRoleVO sysUserRoleVO = new SysUserRoleVO();
        sysMenuRoleVO.setPkRole(sysRoleVO.getId());
        sysPermissionsMapper.deleteMenuRole(sysMenuRoleVO);
        sysPermissionsMapper.deleteUserRole(sysUserRoleVO);
        return sysPermissionsMapper.deleteRole(sysRoleVO) > 0 ? true : false;
    }


    /**
     * 菜单插入
     *
     * @param sysMenuVO
     * @return
     */
    public boolean insertMenu(SysMenuVO sysMenuVO) {
        sysMenuVO.setCreateTime(new Date());
        return sysPermissionsMapper.insertMenu(sysMenuVO) > 0 ? true : false;
    }

    /**
     * 修改菜单
     *
     * @param sysMenuVO
     * @return
     */
    public boolean updateMenu(SysMenuVO sysMenuVO) {
        sysMenuVO.setUpdateTime(new Date());
        return sysPermissionsMapper.updateMenu(sysMenuVO) > 0 ? true : false;
    }

    /**
     * 删除菜单
     *
     * @param sysMenuVO
     * @return
     */
    public boolean deleteMenu(SysMenuVO sysMenuVO) {
        SysMenuRoleVO sysMenuRoleVO = new SysMenuRoleVO();
        sysMenuRoleVO.setPkMenu(sysMenuVO.getId());
        //删除菜单关联
        sysPermissionsMapper.deleteMenuRole(sysMenuRoleVO);
        return sysPermissionsMapper.deleteMenu(sysMenuVO) > 0 ? true : false;
    }

    /**
     * 角色菜单关联插入
     *
     * @param sysMenuRoleVOList
     * @return
     */
    public boolean insertMenuRole(List<SysMenuRoleVO> sysMenuRoleVOList) {
        return sysPermissionsMapper.insertMenuRole(sysMenuRoleVOList) > 0 ? true : false;
    }

    /**
     * 获取角色列表
     *
     * @param page
     * @param size
     * @return
     */
    public PageInfo<SysRoleVO> getRoleList(Integer page, Integer size) {
        if (page != 0) {
            PageHelper.startPage(page, size);
        }
        List<SysRoleVO> list = sysPermissionsMapper.getRoleList();
        PageInfo<SysRoleVO> pageRest = new PageInfo<SysRoleVO>(list);
        return pageRest;
    }

    /**
     * 拼接左侧菜单数据
     *
     * @return
     */
    public String getTree() {
        SysUserVO loginName = (SysUserVO) SecurityUtils.getSubject().getPrincipal();
        SysRoleVO sysRoleVO = getRoleById(loginName.getId());
        List<Map<String, Object>> tree = getThisRoleMenu(sysRoleVO);
        String html = "";
        for (Map<String, Object> map : tree) {
            html += getHtml(map);
        }

        return html;
    }

    public String getHtml(Map<String, Object> map) {
        String html = "<li class='layui-nav-item'>";
        List<Map<String, Object>> data = (List<Map<String, Object>>) map.get("children");
        if (data.size() > 0) {
            html += " <a href='javascript:;'><i class='iconfont'>&#xe607;</i>" + map.get("title") + "</a>";
            String menu = getChildren(data);
            //只有选中的菜单才能显示
            if (!StringUtils.isEmpty(menu)) {
                html += menu;
            } else {
                return "";
            }
        } else {
            //只有选中的菜单才能显示
            if ((boolean) map.get("checked")) {
                html += "<a href='javascript:;' data-url='" + map.get("menuUrl") + "' data-id=" + map.get("id") + " data-text='" + map.get("title") + "'><span class='l-line'></span>" + map.get("title") + "</a>";
            } else {
                return "";
            }
        }
        return html;
    }

    public String getChildren(List<Map<String, Object>> data) {
        String html = "<dl class='layui-nav-child'>";
        for (Map<String, Object> map : data) {
            if ((boolean) map.get("checked")) {
                html += "<dd><a href='javascript:;' data-url='" + map.get("menuUrl") + "' data-id=" + map.get("id") + " data-text='" + map.get("title") + "'><span class='l-line'></span>" + map.get("title") + "</a></dd>";
            } else {
                return "";
            }
        }
        html += "</dl>";
        return html;
    }

}
